-
Notifications
You must be signed in to change notification settings - Fork 9
Add solutions pages and contact forms #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughThis change introduces new JavaScript classes ( Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (10)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (5)
🔇 Additional comments (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 13
🔭 Outside diff range comments (1)
i18n/de.yaml (1)
832-835
: Pagination labels are swapped (“Weiter” vs. “Zurück”).
pagination_previous
should translate to “Zurück”, andpagination_next
to “Weiter”.
Current wording confuses screen-reader users and breaks keyboard navigation expectations.-translation: "Weiter" # pagination_previous +translation: "Zurück" … -translation: "Zurück" # pagination_next +translation: "Weiter"
🧹 Nitpick comments (13)
assets/js/contactsales.js (1)
1-1
: Remove redundant "use strict" directive.The "use strict" directive is redundant in ES6 modules as they are automatically in strict mode.
-"use strict";
assets/js/becomepartner.js (2)
1-1
: Remove redundant "use strict" directive.JavaScript modules are automatically in strict mode, making this directive unnecessary.
-"use strict"; -
14-18
: Improve form validation robustness.The form validation could be more robust by checking if the form element exists before calling jQuery methods.
- if (!$(this._form)[0].checkValidity()) { - $(this._form).find(':input').addClass('show-invalid'); + if (!this._form || !$(this._form)[0].checkValidity()) { + if (this._form) { + $(this._form).find(':input').addClass('show-invalid'); + }i18n/en.yaml (1)
1293-1293
: Add missing newline at end of file.The file is missing a newline character at the end, which is flagged by the YAML linter.
Apply this fix:
- id: pricing_hub_standard_price_first_year translation: "in the first year" +
assets/js/bookdemo.js (2)
1-1
: Remove redundant "use strict" directive.In ES6 modules and modern JavaScript environments, strict mode is automatically enabled, making this directive unnecessary.
Apply this fix:
-"use strict"; -
14-18
: Consider enhancing form validation feedback.The current validation only adds a generic class and sets a generic error message. Consider providing more specific validation feedback for better user experience.
Consider enhancing the validation to provide field-specific error messages:
if (!$(this._form)[0].checkValidity()) { $(this._form).find(':input').addClass('show-invalid'); - this._feedbackData.errorMessage = 'Please fill in all required fields.'; + // Get specific validation messages from invalid fields + const invalidFields = $(this._form).find(':invalid'); + if (invalidFields.length > 0) { + this._feedbackData.errorMessage = invalidFields[0].validationMessage || 'Please fill in all required fields.'; + } return; }layouts/book-a-demo/single.html (1)
150-160
: Consider removing commented code or implementing the feature.There's a large commented block for email confirmation step. Consider either implementing this feature or removing the commented code to keep the template clean.
If email confirmation is not implemented yet, consider adding a TODO issue or removing the commented code:
- <!-- TODO: Uncomment when email confirmation is implemented - <li class="flex items-start"> - <div class="flex-shrink-0 w-6 h-6 bg-primary rounded-full flex items-center justify-center mr-3 mt-0.5"> - <i class="fas fa-check text-white text-xs"></i> - </div> - <div> - <h4 class="font-medium text-gray-900 mb-1">{{ i18n "book_demo_step_1_title" }}</h4> - <p class="text-sm text-gray-600">{{ i18n "book_demo_step_1_description" }}</p> - </div> - </li> - -->layouts/solutions/single.html (1)
68-70
: Provide a fallbacksrc
for lazy-loaded imagesSome crawlers and privacy-focused browsers block JS-driven lazy-loading. Adding a tiny 1×1 GIF (or the real image) to
src
preserves accessibility/SEO.-<img data-src="{{ .image | default "/img/hub/screenshot-1.png" }}" class="lazyload w-full h-auto" alt="{{ .image_alt | default .title }}"/> +<img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="{{ .image | default "/img/hub/screenshot-1.png" }}" class="lazyload w-full h-auto" alt="{{ .image_alt | default .title }}"/>content/solutions/education.de.html (1)
25-25
: Typo: “Complicance” → “Compliance”- - "Complicance-Tools für Institutionen" + - "Compliance-Tools für Institutionen"content/solutions/ngos.en.html (1)
12-12
: Consistent capitalization: “Data Protection”The hero title capitalizes “NGOs” but not “for”. For consistency with other pages (
Education
, etc.) you might prefer title-case:-hero_title: "Data Protection for NGOs and Non-Profits" +hero_title: "Data Protection for NGOs and Non-Profits"i18n/de.yaml (3)
1076-1078
: Improve wording of trusted-by headline.“Vertrauen von 100+ Organisationen weltweit” reads awkward in German. Prefer using “über” or “mehr als”.
-translation: "Vertrauen von 100+ Organisationen weltweit" +translation: "Vertrauen von über 100 Organisationen weltweit"
1173-1174
: Unnatural phrasing in sales topic question.“Was ist dein Thema?” is uncommon; “Anliegen” fits business communication better.
-translation: "Was ist dein Thema?" +translation: "Worum geht es dir?"
1060-1060
: Minor typography: use non-breaking space before ellipsis.German guidelines prefer a fixed space before the ellipsis to keep it together.
-translation: "Verifizierung läuft… bitte warten." +translation: "Verifizierung läuft … bitte warten."
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
static/img/solutions/education/solutions-education-screenshot-1.png
is excluded by!**/*.png
static/img/solutions/education/solutions-education-screenshot-2.png
is excluded by!**/*.png
static/img/solutions/education/solutions-education-screenshot-3.png
is excluded by!**/*.png
static/img/solutions/ngos/solutions-ngos-screenshot-1.png
is excluded by!**/*.png
static/img/solutions/ngos/solutions-ngos-screenshot-2.png
is excluded by!**/*.png
static/img/solutions/ngos/solutions-ngos-screenshot-3.png
is excluded by!**/*.png
📒 Files selected for processing (31)
assets/js/becomepartner.js
(1 hunks)assets/js/bookdemo.js
(1 hunks)assets/js/contactsales.js
(1 hunks)content/become-a-partner.de.html
(1 hunks)content/become-a-partner.en.html
(1 hunks)content/book-a-demo.de.html
(1 hunks)content/book-a-demo.en.html
(1 hunks)content/contact-sales.de.html
(1 hunks)content/contact-sales.en.html
(1 hunks)content/solutions/_index.de.html
(1 hunks)content/solutions/_index.en.html
(1 hunks)content/solutions/education.de.html
(1 hunks)content/solutions/education.en.html
(1 hunks)content/solutions/health-care.de.html
(1 hunks)content/solutions/health-care.en.html
(1 hunks)content/solutions/human-resources.de.html
(1 hunks)content/solutions/human-resources.en.html
(1 hunks)content/solutions/journalism.de.html
(1 hunks)content/solutions/journalism.en.html
(1 hunks)content/solutions/manufacturing.de.html
(1 hunks)content/solutions/manufacturing.en.html
(1 hunks)content/solutions/ngos.de.html
(1 hunks)content/solutions/ngos.en.html
(1 hunks)data/nav.yaml
(1 hunks)i18n/de.yaml
(1 hunks)i18n/en.yaml
(1 hunks)layouts/become-a-partner/single.html
(1 hunks)layouts/book-a-demo/single.html
(1 hunks)layouts/contact-sales/single.html
(1 hunks)layouts/solutions/list.html
(1 hunks)layouts/solutions/single.html
(1 hunks)
🧰 Additional context used
🪛 HTMLHint (1.5.0)
content/solutions/manufacturing.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/become-a-partner.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/manufacturing.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/book-a-demo.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/human-resources.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/_index.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/_index.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/journalism.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/contact-sales.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/human-resources.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/book-a-demo.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/health-care.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/journalism.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
layouts/solutions/list.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/contact-sales.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/become-a-partner.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/education.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/health-care.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
content/solutions/ngos.de.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
layouts/book-a-demo/single.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
[error] 116-116: Special characters must be escaped : [ < ].
(spec-char-escape)
[error] 116-116: Special characters must be escaped : [ > ].
(spec-char-escape)
[error] 116-116: Tag must be paired, no start tag: [ </textarea> ]
(tag-pair)
[error] 12-12: Tag must be paired, missing: [ ], start tag match failed [
(tag-pair)
[error] 260-260: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 262-262: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 269-269: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 271-271: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
content/solutions/education.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
layouts/become-a-partner/single.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
[error] 77-77: Special characters must be escaped : [ < ].
(spec-char-escape)
[error] 77-77: Special characters must be escaped : [ > ].
(spec-char-escape)
[error] 77-77: Tag must be paired, no start tag: [ </textarea> ]
(tag-pair)
[error] 12-12: Tag must be paired, missing: [ ], start tag match failed [
(tag-pair)
[error] 174-174: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 176-176: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 183-183: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 185-185: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
content/solutions/ngos.en.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
layouts/solutions/single.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
[error] 38-38: Special characters must be escaped : [ < ].
(spec-char-escape)
[error] 38-38: Special characters must be escaped : [ > ].
(spec-char-escape)
[error] 38-38: Tag must be paired, no start tag: [ ]
(tag-pair)
[error] 69-69: Special characters must be escaped : [ < ].
(spec-char-escape)
[error] 69-69: Special characters must be escaped : [ > ].
(spec-char-escape)
[error] 96-96: Special characters must be escaped : [ < ].
(spec-char-escape)
[error] 96-96: Special characters must be escaped : [ > ].
(spec-char-escape)
layouts/contact-sales/single.html
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
[error] 68-68: Special characters must be escaped : [ < ].
(spec-char-escape)
[error] 68-68: Special characters must be escaped : [ > ].
(spec-char-escape)
[error] 68-68: Tag must be paired, no start tag: [ </textarea> ]
(tag-pair)
[error] 12-12: Tag must be paired, missing: [ ], start tag match failed [
(tag-pair)
[error] 202-202: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 204-204: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 211-211: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
[error] 213-213: Duplicate of attribute name [ type ] was found.
(attr-no-duplication)
🪛 Biome (1.9.4)
assets/js/becomepartner.js
[error] 1-1: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
assets/js/contactsales.js
[error] 1-1: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
assets/js/bookdemo.js
[error] 1-1: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
🪛 YAMLlint (1.37.1)
i18n/en.yaml
[error] 1293-1293: no new line character at the end of file
(new-line-at-end-of-file)
🔇 Additional comments (31)
content/solutions/human-resources.en.html (1)
1-8
: Front-matter looks good; HTMLHint warning can be ignoredThe block follows Hugo conventions and matches existing solution records. The
doctype-first
alert is a false positive because the file isn’t a standalone HTML document.content/solutions/manufacturing.de.html (1)
1-8
: Metadata is consistent with other solution cardsNo structural issues found; the
comingsoon
flag and localization are correctly applied.content/solutions/journalism.en.html (1)
1-8
: No issues detectedThe front-matter is valid and aligned with the newly introduced solutions architecture.
content/solutions/health-care.de.html (1)
1-8
: German solution record looks correctFields, icon, and
comingsoon
state mirror other entries; ready to publish once content is available.assets/js/contactsales.js (4)
5-56
: LGTM: Well-structured form handler class.The ContactSales class follows good practices with:
- Clear separation of concerns
- Proper error handling
- Consistent feedback state management
- Appropriate use of async operations
3-3
: STORE_API_URL is properly definedThe
STORE_API_URL
constant is declared in both environment files, so it will be available whencontactsales.js
loads:
- assets/js/const.prod.js:
const STORE_API_URL = 'https://store.cryptomator.org/api';
- assets/js/const.dev.js:
const STORE_API_URL = 'http://localhost:8787/api';
No further action needed.
36-36
: ✅subscribeToNewsletter
is defined
The functionsubscribeToNewsletter(email, listId)
is declared inassets/js/newsletter.js
.No further changes are required in
assets/js/contactsales.js
—just ensure thatassets/js/newsletter.js
is loaded beforecontactsales.js
in your HTML or bundler configuration so the global function is available at runtime.
14-18
: All good: jQuery is loaded before deferred page scripts.In
layouts/_default/baseof.html
, jQuery is included (lines 106–107) as a regular<script>
immediately after the"script"
block. Because yourcontactsales.js
is injected in that block withdefer
, it will only execute after the parser finishes and after jQuery has already loaded and run. No changes needed.content/book-a-demo.en.html (1)
1-5
: LGTM: Proper Hugo frontmatter structure.The frontmatter is correctly structured with appropriate metadata for the demo booking page. The HTML doctype warning is a false positive since this is a Hugo content file with YAML frontmatter, not an HTML document.
content/book-a-demo.de.html (1)
1-5
: LGTM: Consistent localized frontmatter.The German frontmatter maintains consistency with the English version while providing appropriate localization. The structure follows Hugo conventions correctly.
content/become-a-partner.de.html (1)
1-5
: LGTM: Well-structured partner page frontmatter.The frontmatter follows the established pattern with proper German localization for the partner program page. The metadata structure is consistent with other content files in the PR.
content/contact-sales.en.html (1)
1-5
: LGTM: Professional contact sales page frontmatter.The frontmatter provides clear, professional metadata for the contact sales page. The structure is consistent with other content files and properly integrates with the associated JavaScript module and template.
content/contact-sales.de.html (1)
1-5
: Front-matter is valid for Hugo – safe to ignore HTMLHint’s “doctype-first” warningThe file is correctly limited to YAML front-matter; adding a
<!DOCTYPE>
would break Hugo parsing. No action required.content/solutions/manufacturing.en.html (1)
1-8
: Metadata looks good; HTMLHint warning is a false positiveAs with all Hugo content files, the absence of a
<!DOCTYPE>
declaration is intentional. Everything else (type, card fields, coming-soon flag) is consistent with the other solution pages.content/solutions/_index.en.html (1)
1-5
: Valid index front-matter; nothing to changePage title, type, and description align with the new navigation entry. Ignore the static-analysis “doctype-first” complaint.
content/become-a-partner.en.html (1)
1-5
: Front-matter OK; static analysis warning not applicableThe partner page metadata follows the same pattern as other content files. No issues.
content/solutions/journalism.de.html (1)
1-8
: German solution entry looks consistentAll required card fields are present; “comingsoon: true” flag matches other upcoming pages. Safe to ignore the HTMLHint warning.
content/solutions/_index.de.html (1)
1-5
: LGTM! Clean Hugo front matter structure.The front matter is properly structured with appropriate German localization for the solutions index page.
content/solutions/human-resources.de.html (1)
1-8
: LGTM! Consistent solution page structure.The front matter follows the established pattern for solution pages with proper German localization and appropriate metadata for card display and "coming soon" status.
content/solutions/health-care.en.html (1)
1-8
: LGTM! Appropriate healthcare solution metadata.The front matter is well-structured with healthcare-specific content including HIPAA compliance mention and appropriate icon choice.
layouts/solutions/list.html (2)
1-61
: Well-structured template with good accessibility.The template is well-organized with clear sections, proper conditional rendering, and good accessibility features like semantic HTML and appropriate ARIA considerations.
10-10
: Sorting Behavior Verified: No Changes NeededHugo’s
.ByParam "comingsoon"
sorts boolean values in ascending order (false
beforetrue
), so pages withcomingsoon = false
(available solutions) already appear before those withcomingsoon = true
(“coming soon”). No reversal is required.
- layouts/solutions/list.html: the existing
{{ range .Pages.ByParam "comingsoon" }}
correctly yields available solutions first.assets/js/becomepartner.js (2)
5-56
: Well-structured class with clear separation of concerns.The class properly encapsulates form handling logic with clear methods for success/failure scenarios and good integration with the feedback system.
3-3
: STORE_API_URL is declared in your config files
STORE_API_URL is defined in:
- assets/js/const.dev.js
- assets/js/const.prod.js
Ensure these files are included before assets/js/becomepartner.js (and any other scripts that reference STORE_API_URL) so the global is available at runtime.
i18n/en.yaml (1)
1061-1293
: LGTM! Comprehensive localization additions.The extensive set of new translation keys provides excellent coverage for the new solutions, demo booking, contact sales, and partner program features. The translation keys follow consistent naming conventions and are well-organized by feature area.
assets/js/bookdemo.js (1)
5-56
: LGTM! Clean class structure with proper error handling.The BookDemo class follows a clean structure with proper separation of concerns, appropriate error handling, and good integration with the UI feedback system.
content/solutions/ngos.de.html (1)
1-110
: LGTM! Comprehensive German NGO solutions content.This well-structured content file provides excellent coverage for NGO use cases with:
- Clear hero messaging for data protection in humanitarian contexts
- Detailed use cases for different NGO types (humanitarian, charitable, international, advocacy)
- Comprehensive key features highlighting zero-knowledge encryption and access control
- Success stories section with placeholder for future case studies
The German localization appears professional and appropriate for the target audience. The static analysis HTML warnings are false positives since this is a Hugo front matter file, not an HTML document.
content/solutions/education.en.html (1)
1-110
: LGTM! Excellent education sector solutions content.This content file provides comprehensive coverage for educational data protection with:
- Relevant use cases spanning universities, research institutions, K-12 schools, and online learning
- Detailed key features emphasizing academic data protection, access control, and research collaboration
- Success stories from recognizable educational institutions
- Professional messaging that addresses educational sector compliance and security needs
The static analysis HTML warnings are false positives since this is a Hugo content file with YAML front matter, not an HTML document.
layouts/book-a-demo/single.html (2)
1-251
: Excellent Alpine.js integration with comprehensive form handling.This template demonstrates excellent use of Alpine.js for reactive state management, with:
- Clean separation of form data, feedback state, and UI logic
- Comprehensive form validation and error handling
- Good accessibility with proper labels and ARIA attributes
- Professional UI design with sidebar information
- Proper integration with CAPTCHA and newsletter subscription
The overall implementation is well-structured and provides a great user experience.
116-116
: No escaping issues detected in textarea placeholderVerified that the
book_demo_message_placeholder
translations in bothi18n/en.yaml
andi18n/de.yaml
are plain text without embedded quotes or special characters, and Hugo’s built-in templating automatically escapes values within HTML attributes. No further changes are needed for safe rendering.layouts/contact-sales/single.html (1)
8-9
:$refs.captcha
might be undefined
@submit.prevent="contactSales.request(); $refs.captcha.reset()"
assumes thecaptcha.html
partial setsx-ref="captcha"
.
If that partial changes, this line will throw and block submission. Please double-check the partial or guard with optional chaining:-@submit.prevent="contactSales.request(); $refs.captcha.reset()" +@submit.prevent="contactSales.request(); $refs.captcha && $refs.captcha.reset()"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure that you can now merge the js
files into a single hubcontact.js
file. You can just put the formType
inside the submitData
as well, so you don't need the requestData
definition at all.
This PR introduces a comprehensive Solutions section, including dedicated pages for Education and NGOs (with more to follow). These pages highlight detailed use cases, key features, and customer success stories. Additionally, three new interactive contact forms – Book a Demo, Contact Sales, and Become a Partner – have been implemented using Alpine.js for dynamic behavior, with integrated Umami analytics for tracking user interactions.